//
// Created by thomas on 8/13/21.
//

#ifndef TEST_PROTO_H
#define TEST_PROTO_H

#ifdef __cplusplus
extern "C" {
#endif

#define FIXED_TAG           0x4C        /*固定标识*/
#define SLAVE_BROADCAST     0x554D      /*分控广播*/
#define SLAVE_UNICAST       0x556B      /*分控单播*/
#define MASTER_BROADCAST    0xBB5C      /*主控广播*/
#define MASTER_UNICAST      0xBB7A      /*主控单播*/

/**************************************************************
 *********************** 分控同步类型配置 ***********************
 *************************************************************/
#define CMD_SLAVE_SYNC      0x5656      /* 分控同步类型配置命令 */
#define TYP_SLAVE_SYNC      0x1234      /* 标识符，无实际意义 */
typedef enum slave_sync_type
{
    EN_SLAVE_SYNC_TYPE_NETWORK = 1,       /* 网络同步 */
    EN_SLAVE_SYNC_TYPE_BTS = 2,           /* BTS同步 */
    EN_SLAVE_SYNC_TYPE_GPS = 3,           /* GPS同步 */
    EN_SLAVE_SYNC_TYPE_INVALID
} slave_sync_type_en;

typedef enum slave_sync_roleflag
{
    EN_SLAVE_SYNC_ROLE_MASTER = 0xA5A5,   /* 主控标识 */
    EN_SLAVE_SYNC_ROLE_SLAVE = 0x0000,    /* 分控标识 */
} slave_sync_roleflag_en;

typedef struct slave_sync_type_pdu
{
    unsigned char type;                 /* 同步类型 */
    unsigned short roleflag;            /* 角色标识 */
}__attribute__((packed)) slave_sync_type_pdu_st;


/**************************************************************
 ******************** 分控广播设置类命令 (广播)*******************
 *************************************************************/
#define TYP_SLAVE_BROADCAST_OCCA_SET       0xABCD        /*使用率低的广播*/
#define TYP_SLAVE_BROADCAST_FREQ_SET       0x5678        /*使用率高的广播*/
//------------------------------------------------------------
/*分控ID广播设置*/
#define CMD_SLAVE_ID_CONF_OCCA_SET        0x6767        /*使用率低的ID设置及清除命令*/
#define CMD_SLAVE_ID_CONF_FREQ_SET        0x7878        /*使用率高的ID设置及清除命令*/
/*分控ID广播设置类型*/
typedef enum slave_id_set_type
{
    EN_SLAVE_ID_SET_TYPE_CLEAN = 0,          /* 清除分控ID */
    EN_SLAVE_ID_SET_TYPE_AUTO = 1,           /* 自动分配分控ID，仅高频率指令使用！！！*/
    EN_SLAVE_ID_SET_TYPE_SPEC = 2,           /* 固定指定的分控ID */
    EN_SLAVE_ID_SET_TYPE_FIRST_FIX = 3,      /* 固定首台分控ID */
    EN_SLAVE_ID_SET_TYPE_ALL_FIX = 4,        /* 固定所有分控ID */
    EN_SLAVE_ID_SET_TYPE_INVALID
} slave_id_set_type_en;

/*使用率低的广播设置指定分控ID时的参数*/
typedef struct slave_id_spec_para
{
    unsigned short oldid;             /*原ID*/
    unsigned short newid;             /*新ID*/
}__attribute__((packed)) slave_id_spec_para_st;

/*使用率低的广播设置首台分控ID时的参数*/
typedef struct slave_id_fist_fix_para
{
    unsigned short id;              /*首台ID*/
}__attribute__((packed)) slave_id_fist_fix_para_st;

/*使用率高的广播设置首台分控ID时的参数*/
typedef struct slave_id_fist_para
{
    unsigned short id;              /*首台ID*/
}__attribute__((packed)) slave_id_fist_para_st;

/*广播设置分控ID的PDU*/
typedef struct slave_id_set_pdu
{
    unsigned char type;         /*enum slave_id_set_type*/
    union id_set_param          /*参数*/
    {
        struct slave_id_spec_para spec_para;
        struct slave_id_fist_fix_para fist_fix_para;
        struct slave_id_fist_para fist_para;
        unsigned int placeholder;       /*占位符，保证此字段4个字节*/
    } __attribute__((packed)) param;
}__attribute__((packed)) slave_id_set_pdu_st;
//------------------------------------------------------------

/*广播设置分控亮度调节*/
#define CMD_SLAVE_BRIGHTNESS_SET     0xDEDE
typedef struct slave_brightness_set_pdu
{
    char save;                  /*0:不保存，1:保存*/
    unsigned short channelA;    /*通道A*/
    unsigned short channelB;    /*通道B*/
    unsigned short channelC;    /*通道C*/
    unsigned short channelD;    /*通道D*/
}__attribute__((packed)) slave_brightness_set_pdu_st;

/*广播设置分控网络千百兆*/
#define CMD_SLAVE_NETSPEED_SET       0xBCBC
typedef enum slave_netspeed_set
{
    EN_SLAVE_NETSPEED_AUTO = 0,
    EN_SLAVE_NETSPEED_100M = 1,
    EN_SLAVE_NETSPEED_INVALID
} slave_netspeed_set_en;

typedef struct slave_netspeed_set_pdu
{
    unsigned char mode;
}__attribute__((packed)) slave_netspeed_set_pdu_st;

/**************************************************************
 ********************* 分控配置查询 (单播)***********************
 *************************************************************/
#define TYP_SLAVE_CONF_READ       0x5C5C
#define CMD_SLAVE_CONF_READ       0x0210

#define TYP_SLAVE_CONF_WRITE      0xABCD
#define CMD_SLAVE_CONF_WRITE      0xCDCD

/*conf_id*/
#define SLAVE_CONF_PARAM_CHECK      0x01        /* 硬件参数确认 */
#define SLAVE_CONF_READ_PARAM       0x02        /* 硬件参数回读 */
#define SLAVE_CONF_DMX_RESET        0x03        /* DMX地址重置 */

#define SLAVE_CONF_ID_CLEAN         0x05        /* 清除分控ID */
#define SLAVE_CONF_ID_AUTO          0x06        /* 自动分配设置分控ID */
#define SLAVE_CONF_ID_SPEC          0x07        /* 固定指定的分控ID */
#define SLAVE_CONF_ID_FIRST_FIX     0x08        /* 固定首台分控ID */
#define SLAVE_CONF_ID_ALL_FIX       0x09        /* 固定所有分控ID */

#define SLAVE_CONF_NETMODE          0x0C        /* 网络千百兆模式 */
typedef struct slave_conf_read_pdu
{
    unsigned char conf_id;
}__attribute__((packed)) slave_conf_read_pdu_st;

/**************************************************************
 ********************* 分控配置回复 (单播)***********************
 *************************************************************/
#define TYP_SLAVE_CONF_ACK           0xA5A5
#define CMD_SLAVE_PARAM_CONF_ACK     0x0601
#define CMD_SLAVE_READ_PARAM_ACK     0x0602
#define CMD_SLAVE_DMX_RESET_ACK      0x0603
#define CMD_SLAVE_NETSPEED_ACK       0x060C
#define CMD_SLAVE_IDSET_ACK          0x0607

typedef struct slave_conf_ack_pdu
{
    unsigned char finished; /*1:完成，其他失败*/
}__attribute__((packed)) slave_conf_ack_pdu_st;

/*ID自动分配确认回复*/
typedef struct slave_id_auto_ack_pdu
{
    unsigned char iface_mode;   /*1表示千/百兆自适应，2表示强制百兆，其他数据无效*/
    unsigned char ifaceA_mode;
    unsigned char ifaceB_mode;
    unsigned char work_mode;    /*0xA5表示应用程序模式，其他表示升级模式；*/
    unsigned char idfixed;      /*ID设置模式：1、固定；0、不固定；*/
    unsigned char ifaceA_isup; /*1：A口连接；其他表示A口未连接；*/
    unsigned char ifaceB_isup;
}__attribute__((packed)) slave_id_auto_ack_pdu_st;

/*分控硬件参数回读回复*/
typedef struct slave_hardware_param_pdu
{
    unsigned char pkgnum;               /*总包数*/
    unsigned char pkgno;                /*分包号*/
    unsigned short pkgsize;             /*分包大小*/
    unsigned short chiptype;            /*LED驱动芯片类型*/
    unsigned short port_ch_num;         /*端口通道数*/
    unsigned char gray_lvl;             /*灰度等级*/
    unsigned short clock_freq;          /*时钟频率*/
    unsigned short clock_freq_read;
    unsigned char ch0_finetune;
    unsigned char dutyrate;             /*占空比*/
    unsigned char gray_filter;           /*低灰过滤*/
    unsigned char color_num;            /*颜色数*/
    unsigned char oe;
    unsigned char gamma_tune_type;      /*伽玛值设置方式，0表示通道整体设置，1表示通道分别设置，其他值无效，默认为0*/
    unsigned short gamma[4];
    unsigned char brightness_tune_type; /*亮度调节设置方式，0表示通道亮度整体设置，1表示通道亮度分别设置，其他值无效，默认为0*/
    unsigned short brightness[4];
    unsigned char reflesh_type;         /*刷新频率方式选择，0表示手动设置刷新频率，1表示自动设置刷新频率，其他值无效，默认为1*/
    unsigned char reflesh_value;        /*刷新频率数值，刷新频率范围会根据芯片类型、带载、频率、灰度等级等因素自动调整，默认值根据芯片而定*/
    unsigned char current_gain[4];      /*电流增益值，默认值待定，分别代表A、B、C、D四通道的电流数值；*/
    unsigned char output_inverse;       /*输出反向，0表示不反向，1表示反向，默认为0不反向；*/
    unsigned char addr_pin_lvl;         /*地址线默认电平为高，0表示为低，1表示为高，默认为1*/
    unsigned char led_hold;             /*信号断开显示状态，0表示保留最后一帧，1表示黑屏，默认为为0*/
}__attribute__((packed)) slave_hardware_param_pdu_st;

typedef struct slave_gammatable_pdu
{
    unsigned char pkgnum;               /*总包数*/
    unsigned char pkgno;                /*分包号*/
    unsigned short pkgsize;             /*gamma表数据大小*/
    unsigned short gammatabl[2][256];   /*gamma表*/
}__attribute__((packed)) slave_gammatable_pdu_st;

/**************************************************************
 ********************* DMX写地址 (单播)***********************
 *************************************************************/
#define TYP_SLAVE_DMX_ADDR_SET       0x2345
#define CMD_SLAVE_DMX_ADDR_SET       0x2323

/*驱动板类型*/
typedef enum slave_board_type
{
    EN_SLAVE_BOARD_TYPE_5PIN = 0,
    EN_SLAVE_BOARD_TYPE_3PIN = 1,
    EN_SLAVE_BOARD_TYPE_INVALID
} slave_board_type_en;

/**
 * 高位表示芯片协议类型:
 *      0x01表示DMX512协议，
 *      02表示断点续传类型，
 *      其他协议类型待定;
 * 低位表示具体厂家芯片型号:
 *
 * 例如0x0102,0x01表示DMX512协议，0x02表示为SM16512芯片； 默认为0x0103
 */
typedef enum led_chip_type
{
    EN_LED_CHIP_TYPE_SM16511 = 0x0101,
    EN_LED_CHIP_TYPE_SM16512 = 0x0102,
    EN_LED_CHIP_TYPE_UCS512C = 0x0103,
    EN_LED_CHIP_TYPE_UCS512C4 = 0x0104,
    EN_LED_CHIP_TYPE_UCS512D = 0x0105,
    EN_LED_CHIP_TYPE_UCS512E = 0x0106,
    EN_LED_CHIP_TYPE_UCS512F = 0x0107,
    EN_LED_CHIP_TYPE_DMX512 = 0x0108,
    EN_LED_CHIP_TYPE_DMX05 = 0x0109,
    EN_LED_CHIP_TYPE_SM18522 = 0x010A,

    EN_LED_CHIP_TYPE_UCS5603 = 0x0201,

    EN_LED_CHIP_TYPE_UCS2903 = 0x0301,
    EN_LED_CHIP_TYPE_UCS8904 = 0x0302,
    EN_LED_CHIP_TYPE_UCS8903 = 0x0303,

    EN_LED_CHIP_TYPE_TM1804 = 0x0401,
    EN_LED_CHIP_TYPE_TM1803 = 0x0402,
} led_chip_type_en;

/*首包地址数据*/
typedef struct dmx_addr_first_pkg
{
    unsigned short datalen[8];      /*端口N数据长度*/
    unsigned short addrdata[512];   /*端口数据，4字节对齐，地址=(灯具ID-1) x 灯具颜色数，2字节表示*/
}__attribute__((packed)) dmx_addr_first_pkg_st;

/*非首包地址数据*/
typedef struct dmx_addr_pkg
{
    unsigned short addrdata[512];   /*端口数据，4字节对齐*/
}__attribute__((packed)) dmx_addr_pkg_st;

/*识别符,固定*/
#define SLAVE_DMX_ADDR_SET_FIX_TAG  0x1234
typedef struct slave_dmx_addr_set_pdu
{
    unsigned short tag;             /*识别符,固定为 SLAVE_DMX_ADDR_SET_FIX_TAG*/
    unsigned char pkgnum;           /*总包数*/
    unsigned char pkgno;            /*分包号*/
    unsigned char board;            /*驱动板类型(enum slave_board_type)，0:5pin(默认)， 1:3pin*/
    unsigned short chip;            /*灯具芯片类型(enum led_chip_type)*/
    char pad[3];                    /*保留字节*/
    union data
    {
        struct dmx_addr_first_pkg first_pkg;    /*首包地址数据*/
        struct dmx_addr_pkg pkg;                /*非首包地址数据*/
    }__attribute__((packed)) pkgdata;/*地址数据*/
}__attribute__((packed)) slave_dmx_faddr_set_pdu_st;

/**************************************************************
 ********************* 视频流传输 (单播)***********************
 *************************************************************/
#define TYP_SLAVE_STREAM_DATA           0x6789
#define CMD_SLAVE_STREAM_DATA           0x4545

/*识别符,固定*/
#define SLAVE_STREAM_DATA_FIX_TAG  0x5678

/*首包视频数据*/
typedef struct stream_first_pkg
{
    unsigned short datalen[8];      /*端口N数据长度*/
    unsigned char addrdata[1436];   /*端口数据，4字节对齐*/
}__attribute__((packed)) stream_first_pkg_st;

/*非首包视频数据*/
typedef struct stream_follow_pkg
{
    unsigned char addrdata[1460];
}__attribute__((packed)) stream_follow_pkg_st;

typedef struct slave_stream_data_pdu
{
    unsigned short tag;             /*识别符,固定为 SLAVE_STREAM_DATA_FIX_TAG*/
    unsigned char pkgnum;           /*总包数,1-25*/
    unsigned char pkgno;            /*分包号*/
    char pad[6];                    /*保留字节*/
    union stream
    {
        struct stream_first_pkg first_pkg;    /*首包视频数据*/
        struct stream_follow_pkg follow_pkg;
    }__attribute__((packed)) streamdata;/*视频数据*/
}__attribute__((packed)) slave_stream_data_pdu_st;

//=============================================================
typedef struct akltproto
{
/*B0*/      unsigned char salt;         /* 随机数 */
/*B1*/      unsigned char tag;          /* 固定标识 0x4C */
/*B2-3*/    unsigned short ubflag;      /* 广播 or 单播标识*/
/*B4-5*/    unsigned short type;        /* 命令大类 */
/*B6-7*/    unsigned short id;          /* 分控ID */
/*B8-9*/    unsigned short cmd;         /* 命令类型 */
    unsigned char *data;                /* 数据(明文)*/
    unsigned int size;
} __attribute__((packed)) akltproto_st;


int aklt_proto_encode(unsigned char *buf, unsigned short type, unsigned short cmd, unsigned short id,
                      unsigned char *data, unsigned int length, unsigned short ubflag);

int aklt_proto_decode(struct akltproto *aklt, const unsigned char *data, unsigned int length);

#ifdef __cplusplus
}
#endif

#endif //TEST_PROTO_H
